package dispatch

import (
	"math/rand"
)

/*
	dispatch寻址
*/

type addressing struct {
	svc  string
	addr string
}

const maxWeight = 10

func NewAddress(svc string, opts ...func(*addressing)) *addressing {
	address := &addressing{svc: svc}
	for _, opt := range opts {
		opt(address)
	}
	return address
}

// with max weight is default used
// when  weight is 0, it will not be used
func WithWeight() func(*addressing) {
	return func(c *addressing) {
		instance := dispatchInstance().NodePord(c.svc)
		addrs := make([]string, 0)
		for _, addrResult := range instance {
			if addrResult.Weight <= 0 {
				addrResult.Weight = 0
			}
			if addrResult.Weight > maxWeight {
				addrResult.Weight = maxWeight
			}
			for i := 0; i < addrResult.Weight; i++ {
				addrs = append(addrs, addrResult.Addr)
			}
		}
		c.addr = addrs[rand.Intn(len(addrs))]
		// log.Default().Printf("dispatch addrs %v", addrs)
		// log.Default().Printf("return dispatch addr %v", c.addr)
	}
}

// 随机负载
func WithRand() func(*addressing) {
	return func(c *addressing) {
		instance := dispatchInstance().NodePord(c.svc)
		c.addr = instance[rand.Intn(len(instance))].Addr
	}
}

func (address *addressing) Addr() string {
	return address.addr
}

func (address *addressing) Svc() string {
	return address.svc
}
